#include "stdafx.h"
#pragma hdrstop

#include "MessageQueue.h"
#include "LengthField.h"
#include "Lockable.h"
#include "P3Exception.h"
#include <stdexcept>

using namespace std;

void MessageQueue::QueueMessage( std::istream& is )
{
	MessageQueueEntry entry = { 0, 0, NULL };
	entry.descSupp = is.get() << 8;
	entry.descSupp |= is.get();
	LengthField<2> length;
	length.ReadBinary( is );
	if( is )
	{
		entry.length = length;
		try
		{
			entry.message = new char[length];
			if( length > 0 )
			{
				is.read( entry.message, length - 1 );
				entry.message[length - 1] = is.get();
			}
		}
		catch( bad_alloc& )
		{
			is.setstate( ios::failbit );
		}
		if( is )
		{
			::Lock<MessageQueue> lock( *this );
			this->push( entry );
		}
		else
		{
			delete[] entry.message;
			throw p3exception(
				"Malformed message received, "
				<< "DescSupp: 0x" << hex << entry.descSupp << ", "
				<< "length: " << dec << length
				);
		}
	}
}

bool MessageQueue::Empty() const
{
	::Lock<const MessageQueue> lock( *this );
	return this->empty();
}

MessageQueueEntry MessageQueue::Next()
{
	::Lock<MessageQueue> lock( *this );
	MessageQueueEntry result = this->front();
	this->pop();
	return result;
}